<?php
//团队积累
//单字幕函数 +----------------------------------------------------------------------
/**
 * 打印变量,断点
 * @param unknown $a 变量
 * @param string $b  是否打印变量类型
 */
function t($a, $b = false) {
    echo "<pre>";
    if ($b) {
        var_dump($a);
    } else {
        print_r($a);
    }
    exit("</pre>");
}

/**
 * 页面输出
 * @param string $msg 信息
 * @param string $exit 是否阻断
 */
function e($msg='', $exit = false){
    if($exit){
        exit("------------------{$msg}-------------------<br>");
    }else{
        echo("------------------{$msg}-------------------<br>");
    }
}

function l($key='', $type='zh'){
    return db('lang')->where('type',$type)->where('key',$key)->value('val');
}

/**
 * 获取配置
 * @param string $name  配置一级键值的名称
 * @param string $key   配置二级键值的名称
 * @return \think\mixed
 */
function c($name = '', $key = ''){
    //取数据库
    $d = [
    ];
    if( in_array($name, $d) ){
        $rs = db('sys')->where('k', $name)->value('v');
        if( $rs )
            return $rs;            
    }
    
    $rs = \think\Config::get($name);
    if( $key!=='' ){
        return isset($rs[$key]) ? $rs[$key] : "";
    }   
    return $rs;
}

/**
 * URL重定向
 * @param string  $url   重定向的URL地址
 * @param integer $time  重定向的等待时间（秒）
 * @param string  $msg   重定向前的提示信息
 * @return 跳转页面
 */
function r($url, $time = 0, $msg = '') {
    if (empty($msg))
        $msg = "系统将在{$time}秒之后自动跳转到{$url}！";

    if (!headers_sent()) {
        if (0 === $time) {
            header('Location: ' . $url);
        } else {
            header("refresh:{$time};url={$url}");
            echo ($msg);
        }
    } else {
        $str = "<meta http-equiv='Refresh' content='{$time};URL={$url}'>";
        if ($time != 0) {
            $str .= $msg;
        }
        echo ($str);
    }
    exit;
}

//判断函数 +----------------------------------------------------------------------
function is_post(){
    return request()->isPost();
}
//匹配是否为UTF-8编码
function is_utf8($utf8str)
{
    if (preg_match('/^([' . chr(228) . '-' . chr(233) . ']{1}[' . chr(128) . '-' . chr(191) . ']{1}[' . chr(128) . '-' . chr(191) . ']{1}){1}/', $utf8str) == true || preg_match('/([' . chr(228) . '-' . chr(233) . ']{1}[' . chr(128) . '-' . chr(191) . ']{1}[' . chr(128) . '-' . chr(191) . ']{1}){1}$/', $utf8str) == true || preg_match('/([' . chr(228) . '-' . chr(233) . ']{1}[' . chr(128) . '-' . chr(191) . ']{1}[' . chr(128) . '-' . chr(191) . ']{1}){2,}/', $utf8str) == true) {
        return true;
    } else {
        return false;
    }
}

function attach($path){
    return $path?"\\".$path:"";
}
//通用函数 +----------------------------------------------------------------------
/**
 * 读取文件
 * @param unknown $file_path  文件路径
 * @param number $l           开始行
 * @param number $length      偏移量
 * @return multitype:string
 */
function com_read_file($file_path,$length=1, $start=0){
    $d  = [];
    $fp = new SplFileObject($file_path, 'rb');
    $fp->seek($start);
    for($i = 0; $i < $length; ++$i) {
        $d[]=$fp->current();
        $fp->next();
    }
    return $d;
    
    
    
    
    /*
    t($file_path);
    #结束行
    $end = $l+$length;
    
    #打开文件
    $fp = fopen($file_path , 'r');
    t($fp);
    $d  = [];
    
    #读取
    $i = 0;
    while (!feof($fp)) {
        $i++;
        echo $i."=".$l."=".$end;
        if($i>$l && $i<=$end){
            $c   = stream_get_line($fp, 65535, "\n");
            if($c) $d[] = $c;
        }
    }
    return $d;
    */ 
}
/**
 * 获取sql
 */
function com_sql(){
    $sql = \think\Db::getLastSql();
    t($sql);
}
/**
 * 获取系统配置
 * @param unknown $k
 */
function com_sys( $k = [] ){
    return \app\common\model\Sys::get($k);
}

/**
 * 统计日志
 * @param unknown $data 统计的日志数据
 * @param string $name  日志文件名
 */
function com_log($data=[],$name='log'){
    if(is_string($data))
        $data = ['default'=>$data]; 
    $str="\r\n-----------------------------------------".date("Y-m-d H:i:s")."-----------------------------------------\r\n";
    foreach($data as $key=>$val)
    {
        $val = is_string($val) ? $val : json_encode($val);
        $str.="$key:$val\r\n";
    }
    $dir = __DIR__."/../public/uploads/logs/".date("Ym")."/";
    com_mkdir($dir);
    $file = "$name".date("Ymd").".txt";
    file_put_contents($dir.$file, $str,FILE_APPEND);
}


/**
 * 新建csv
 * @param unknown $data  数据库搜索出来的数据
 * @param unknown $title txt表头
 * @param unknown $field 表头对应的字段
 * @param unknown $pre  文件名前缀
 * @param unknown $type  文件类型  csv/txt
 * @return string
 */
function com_down_csv( $data, $title=[], $field=[], $pre='', $type='csv' ){
    $content = "";
    //标题
    foreach($title as $val){
        $content .= $val.",";
    }
    $content = rtrim($content, ",")."\r\n";

    //内容
    foreach( $data as $val ){
        foreach($field as $f){
            $content .= str_replace(array(","),array(""),$val[$f]).",";
        }
        $content = rtrim($content, ",")."\r\n";
    }
    $dir = c('uploads')."csv/".date("Y-m")."/".date("d");
    com_mkdir( $dir );
    $filename = $dir."/".$pre."_".time().".".$type;
    file_put_contents($filename, $content);
    return "http://".$_SERVER['HTTP_HOST']."/".$filename;
}


/**
 * 重置url
 * @param unknown $url    原始的url
 * @param unknown $param  需添加的参数数组
 * @param string $is_urlencode 是否转义
 * @return string
 */
function com_build_url($url, $param=[], $is_urlencode=false){
    foreach($param as $k => $v){
        $url = preg_replace('/(&|\?)'.$k.'=[^&]+/', '', $url);
        if(!$v)
            continue;
        if($is_urlencode){
            $k = urlencode($k);
            $v = urlencode($v);
        }
        $url .= strpos($url,'?') === false ? '?'.$k.'='.$v : '&'.$k.'='.$v;
    }
    return $url;
}

/**
 * 验证类型
 * @param string $url 链接地址
 * @param unknown $ext 后缀类型
 */
function com_check_type($url = '', $ext = ['gif','jpeg','jpg','png','bmp']){
    $arr = explode('.',$url);
    $e   = end($arr);
    return in_array($e,$ext);
}

/**
 * 取得图片绝对路径
 * @param string $path   图片相对路径
 * @param string $type   图片类型  small/middle
 * @param string $check   是否返回404图片
 * @return 返回图片绝对路径
 */
function com_get_pic($path = '', $type = '', $check = false, $is_domain = false ){
    $domain =  $is_domain ? "http://{$_SERVER['HTTP_HOST']}/" : "";
    if(empty($path)){
        return $check ? "./static/404.png" : '';
    } 

    $file = $path;
    if( in_array($type, array('small', 'middle')) ){
        $file = dirname($path) . "/" . $type . "_" . basename($path);
        if(!is_file(APP_PATH."../public/".$file)){
            $file = dirname($path) . "/" . basename($path);
        }
    }   
    if( $check && !is_file(APP_PATH."../public/".$file) ){
        $file = "./static/404.png";
    }
    return $domain.$file;
}
/**
 * 远程采集图片到临时文件
 * @param string $url  采集的地址
 * @param string $filename  采集之后的名称， 不填写则为时间戳
 * @return string|\my\false;
 */
function com_fetch_pic( $url='', $filename="" ){
    if(!$url) return '';

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; SeaPort/1.2; Windows NT 5.1; SV1; InfoPath.2)");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
    $data = curl_exec($ch);
    if (curl_errno($ch) !== 0) {
        return com_error(['curl错误'.curl_errno($ch)]);
    }
    curl_close($ch);
    $ext = strrchr($url, ",");
    $ext = in_array($ext, ['.gif','.jpg','.bmp']) ? $ext : ".jpg";
    $filename = $filename ? $filename : time().rand(1000,999).$ext;
    $dir = c('uploads')."temp/".date("Ym")."/".date("d")."/";
    com_mkdir($dir);
    $path = $dir.$filename;
    file_put_contents($path,$data);
    return $path;
}
/**
 * 获取文件大小
 * @param unknown $file  文件路径
 * @return string
 */
function com_get_filesize( $file ){
    $perms=stat($file);
    $size = $perms['size'];
    $a    = ['B', 'KB', 'MB', 'GB', 'TB'];
    $pos  = 0;
    while ($size >= 1024) {
        $size /= 1024;
        $pos++;
    }
    return round($size, 2). $a[$pos];
}

/**
 * 获取文件修改时间
 * @param unknown $file 文件路径
 * @return string
 */
function com_get_filetime( $file ){
    return date("Y-m-d H:i:s", filemtime($file));
}

/**
 * 返回当前页页码
 * @param unknown $total     总条数
 * @param number  $page      页码
 * @param number  $page_size 每页显示条数
 * @return 页码
 */
function com_cur_page($total, $page = 1,  $page_size = 12){
    return \my\Page::curPage($total, $page, $page_size);
}   
/**
 * 返回分页数据
 * @param unknown $total 总条数
 * @param unknown $page  当前页码
 * @param unknown $page_size  每页显示条数
 * @return 分页原始数据
 */
function com_page_data( $total, $page = 1,  $page_size = 12 ){
    return \my\Page::getData($total,$page,$page_size);
}   
/**
 * 组建后端ajax的table列表
 * @param unknown $list    列表数据
 * @param unknown $arr     格式化列的key值
 * @return  列表 tbody html
 */
function com_build_table($list, $arr){
    return \my\Html::buildTable($list, $arr);
}
/**
 * 组件分页html
 * @param unknown $data 分页数据的原始数据
 * @return 分页html
 */
function com_build_page( $data = [], $type=1 ){
    if($type==1){
        return \my\Html::buildPage($data);
    }else if($type==2){
        return \my\Html::buildPage2($data);
    }else if($type==3){
        return \my\Html::buildPage3($data);
    }
}

/**
 * 重写TP5验证，封装到前端
 * @param unknown $rule 规则
 * @param unknown $msg  提示
 * @param unknown $data 数据
 * @param boolean $exit  是否输出到前端
 * @return boolean
 */
function com_validate( $rule, $msg, $data, $exit = false ){
    $v = new \think\Validate($rule, $msg);
    $v->batch();
    if( $v->check($data) )
        return true;
    //把错误捕捉到前端类里
    com_error( $v->getError() );
    //错误处理
    if($exit){
        $config = [
            'err' => ['return_type'=>'json'],
        ];
    }else{
        $config = [
            'err' => ['return_type'=>'return'],
        ];
    }
    return com_check($config);
}

/**
 * 密码
 * @param string $password
 */
function com_password($password = '123456'){
    $str = "abcdefghijklmnopqrstuvwxyz";
    return md5($password.$str);
}

/**
 * 上传单个图片//允许类型 'jpg', 'gif', 'png', 'jpeg','ico'
 * @param string $dir          目录
 * @param string $name          上传字段名称
 * @param string $is_thumb      是否生成缩略图
 * @param unknown $con_thumb    缩略图大小配置
 * @return 返回路径
 */
function com_up_pic( $dir='article', $name='pic', $is_thumb = true, $con_thumb = ['small'=>[100,100], 'middle'=>[300,300]] ){
    return \my\Up::upPic($dir,$name,$is_thumb,$con_thumb);
}

/**
 * 上传文件
 * @param string $dir  上传到目录
 * @param string $name  上传文件字段
 * @param unknown $exts 允许文件的后缀名
 * @return 返回路径
 */
function com_up_file($dir='rsa', $name='pic', $exts = []){
    return \my\Up::upFile($dir,$name, $exts);    
}
/**
 * 解压文件到指定目录
 *
 * @param   string   zip压缩文件的路径
 * @param   string   解压文件的目的路径
 * @param   boolean  是否以压缩文件的名字创建目标文件夹
 * @param   boolean  是否重写已经存在的文件
 * @return  boolean  返回成功 或失败
 */
function com_unzip($src_file, $dest_dir=false, $create_zip_name_dir=true, $overwrite=true){
    $zip = zip_open($src_file);
    if(!$zip)
        return false;
    
    $splitter = ($create_zip_name_dir === true) ? "." : "/";
    if($dest_dir === false)
        $dest_dir = substr($src_file, 0, strrpos($src_file, $splitter))."/";
    com_mkdir($dest_dir);
    
    
    while ($zip_entry = zip_read($zip)){
        if ( !zip_entry_open($zip,$zip_entry,"r") )
            continue;
        
        $file_name = $dest_dir.zip_entry_name($zip_entry);
        if ($overwrite === true || $overwrite === false && !is_file($file_name)){
            
            if(substr($file_name,-1)=='/'){
                com_mkdir($file_name);
            }else{
                $fstream = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
                file_put_contents($file_name, $fstream);
            }
            chmod($file_name, 0777);
            echo "save: ".$file_name."<br />";
        }
        zip_entry_close($zip_entry);
    }
    zip_close($zip);
    return true;
}

/**
 * 递归创建目录
 * @param unknown $dir  文件路径
 * @return true or false
 */
function com_mkdir( $dir ){
    if ( is_dir($dir) || @mkdir($dir) ) return true;
    if ( !com_mkdir(dirname($dir)) ) return false;
    return @mkdir($dir,0777);
}
/**
 * 下载excle
 * @param unknown $data   内容
 * @param unknown $title  标题
 * @param unknown $field  内容的过滤字段
 * @param unknown $type  文件位置/文件名   
 * @return 返回文件的绝对路径
 */
function com_csv( $data, $title=[], $field=[], $type ){
    $content = "";
    //标题
    foreach($title as $val){
        $content .= $val.",";
    }
    $content = rtrim($content, ",")."\r\n";
    //内容
    foreach( $data as $val ){
        foreach($field as $f){
            $content .= str_replace(array(","),array(""),$val[$f]).",";
        }
        $content = rtrim($content, ",")."\r\n";
    }
    $dir = c('uploads')."csv/".date("Y-m")."/".date("d");
    com_mkdir( $dir );
    $filename = $dir."/".$type."_".time().".csv";
    file_put_contents($filename, $content);
    return "http://".$_SERVER['HTTP_HOST']."/".$filename;
}
/**
 * 截取utf8字符串,完美支持中文
 * @param: 待截取的字符串,从第几个字符开始截取，截取长度，如超过长度是否加“..”
 * @param string $str 截取的字符串
 * @param int   $len  截取长度
 * @param int   $from 从那个位置开始截取
 * @param string $adddot  截取后用什么填充 默认...
 */
function com_substr($str, $len, $adddot = '...', $from = 0) {
    if ($adddot && mb_strlen($str, 'utf-8') > intval($len)) {
        return preg_replace('#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,' . $from . '}' . '((?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,' . $len . '}).*#s', '$1', $str) . $adddot;
    } else {
        return preg_replace('#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,' . $from . '}' . '((?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,' . $len . '}).*#s', '$1', $str);
    }
}


/**
 * 返回ip地址或IPV4数字
 * @param number $type 0返回ip， 1返回数字
 * @return ip地址
 */
function com_client_ip( $type = 0 ){
    $type       =  $type ? 1 : 0;
    static $ip  =   NULL;
    if ($ip !== NULL) return $ip[$type];
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $arr    =   explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        $pos    =   array_search('unknown',$arr);
        if(false !== $pos) unset($arr[$pos]);
        $ip     =   trim($arr[0]);
    }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
        $ip     =   $_SERVER['HTTP_CLIENT_IP'];
    }elseif (isset($_SERVER['REMOTE_ADDR'])) {
        $ip     =   $_SERVER['REMOTE_ADDR'];
    }
    // IP地址合法验证
    $long = ip2long($ip);
    $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
    return $ip[$type];
}
/**
 * 返回服务器ip
 */
function com_server_ip(){
    return gethostbyname($_SERVER["SERVER_NAME"]);
}

/**
 * 产生token值
 * @param string $user_id  用户id, 或者其他
 */
function com_token( $user_id = '' ){
    $str = time().rand(100,999).$user_id;
    return md5($str);
}
/**
 * 生成订单号
 * @return  string
 */
function com_order_no()
{
    $id = db('temp_id')->insertGetId(['t'=>1]);
    return date('YmdHi').(1000000+$id);
}

/**
 * 捕捉错误
 * @param unknown $error_data  错误数据
 * @param number $code         错误码
 */
function com_error( $error_data = [], $code = 100 ){
    return \my\Front::error($error_data, $code);
}

/**
 * 验证错误，并处理前端交互
 * @param unknown $config  返回前端参数
 * @param string $is_api   是否是api
 * @return 返回 bool or exit json
 */
function com_check($config = [], $is_api = false ){
    return \my\Front::check($config, $is_api);
}
/**
 * 获取模块名称
 */
function com_module(){
    $request = \think\Request::instance();
    return strtolower($request->module());
}
/**
 * 获取控制器名称
 */
function com_controller(){
    $request = \think\Request::instance();
    return strtolower($request->controller());
}
/**
 * 获取动作名称
 */
function com_action(){
    $request = \think\Request::instance();
    return strtolower($request->action());   
}
/**
 * 取得后台登陆用户信息
 * @param string $field 字段名称， 可取单个字段值
 */
function com_admininfo( $field = '' ){
    return \my\G::get('admininfo', $field);
}
/**
 * 取得前台登陆用户信息
 * @param string $field 字段
 */
function com_userinfo( $field = '' ){
    return \my\G::get('userinfo', $field);
}


/*============*/
/**
 * 格式化显示时间
 * @param unknown $time 时间
 * @param string $format 格式
 * @return string
 */
function com_format_time($time, $format="Y-m-d H:i"){
    return $time ? date($format, $time) : "";
}
/**
 * 格式化多选删除选项框
  * @param unknown $id 主键id值
  * @return string
  */
function com_format_checkbox( $id ){
    return "<input type='checkbox' name='id[]' tid='{$id}'>";
}
/**
 * 格式化qq显示
 * @param string $qq  qq号
 * @param string $islink  是否快捷联系QQ    
 * @return string
 */
function com_format_qq( $qq='', $islink=true){
    if($qq){
        return  $islink ? "<a target='_blank' href='tencent://message/?uin={$qq}&amp;Site=qq&amp;Menu=yes'>{$qq}</a>" : $qq;
    }else{
        return "";
    }   
}
/**
 * 格式化显示链接
 * @param string $link
 * @return string
 */
function com_format_a( $link='' ){
    return $link ? "<a target='_blank' href='{$link}'>{$link}</a>" : "";
}

/**
 * 格式化图片html
 * @param unknown $path  图片路径
 * @param number $height 高度
 * @param string $width  宽度
 */
function com_format_pic($path, $height=50, $width='auto'){
    return $path ? "<img src='\\{$path}' height={$height} style='width:{$width};' />" : "";    
}

/**
 * 打开新页面
 * @param unknown $p
 */
function com_page( $p = [], $type='a' ){
    #默认字段
    $temp = [
        #样式
        'title'     => '编辑',
        'ptitle'    => '',
        'width'     => '',
        'height'    => '',
        'confirm'   => '',
        'ico'       => '',
        'txt'       => '',
        'val'       => '',
    
        #动作
        'url'       => '',
        'checkurl'  => '',
        'post'      => [],
        'temp'      => [],
    ];
    $p = array_merge( $temp, array_intersect_key($p,$temp) );
    if(empty($p['ptitle'])) $p['ptitle'] = $p['title'];


    #提交数据
    $post = $p['post'];
    $p['post'] = json_encode($post);
    
    #url ajax路径
    $url = $p['url'];
    
    #本身的值
    $val = $p['val'];
    unset($p['val']);
    
    #select 备选数据
    $tmp = $p['temp'];
    unset($p['temp']);
    
    #图表或文字
    $ico = "Hui-iconfont-".$p['ico'];
    $txt = !empty($p['txt']) ? $p['txt'] : "<i class='Hui-iconfont {$ico}'></i>";
    
    if($type=='a'){
        $html  = "<a title='{$p['title']}' class='ml-5' onclick='c_action(this)' href='javascript:;' ";
        unset($p['title']);
        unset($p['ico']);
        unset($p['txt']);
        foreach($p as $k => $v){
            $html .= "_{$k}='{$v}' ";
        }
        $html  .= ">{$txt}</a>";
    }elseif($type=='input'){
        $html = "<input style='width:40px;padding:5px;' type='text' _url='{$url}' _t='{$post['t']}' _id='{$post['id']}' _f='{$post['f']}' onchange='c_change(this)' value='{$val}' />";
    }elseif($type=='select'){
        $html = "<select style='width:100px;'  _url='{$url}' _t='{$post['t']}' _id='{$post['id']}' _f='{$post['f']}'  onchange='c_change(this)'>";
        foreach($tmp as $k => $v){
            $selected = $k==$val ? "selected=true" : "";
            $html    .= "<option value='{$k}' ".$selected.">{$v}</option>";
        }
        $html .= "</select>";
    }elseif($type=='iphone'){
        $html = "<div class='iphone_switch' status='{$val}' data-on-label='开' data-off-label='关'>
                 <input type='checkbox'  ".($val?'':'checked')."  _url='{$url}' _t='{$post['t']}' _id='{$post['id']}' _f='{$post['f']}'  onchange=\"c_change(this,'iphone')\" />
                 </div>";
    }
    return $html;
}

/**
 * 格式化数据
 * @param unknown $d
 */
function com_data( $d ){
    if(isset($d['file'])) unset($d['file']);
    if(isset($d['input-file'])) unset($d['input-file']);
    
    $temp  = [];
    $field = [];
    foreach($d as $k => $v){
        if(strpos($k, 'del_')===0){
            $field[] = ltrim($k,'del_');
        }else{
            $temp[$k] = $v;
        }
    }
    foreach($field as $k){
        if(isset($temp[$k]))
            $temp[$k] = "";
    }
    return $temp;
}

/**
 * 格式化上传图片输入框
 * @param unknown $url
 * @param string $val
 */
function com_c_up($url, $f='', $val='',$type='add'){
   if($type=='edit'){
       $html = "<input type='file' name='file' lay-type='file' _url='{$url}' onclick=\"c_up(this)\">";
       if($val){
           $html .= "<span _span='{$f}'>";
            if(com_check_type($val)){#图片
                $html .= "<img src='\\{$val}' height=50 />";
            }else{#文件
                $html .= "<a target='_blank' style='font-size:36px;' href='\\{$val}'><i class='Hui-iconfont Hui-iconfont-file'></i></a>";
            }
            $html .= "<input type='hidden' name='{$f}' value='{$val}' />";
            $html .= "<input type='checkbox' name='del_{$f}' value='1' title='删除' />";
            $html .= "</span>";
       }
   }else{
       $html = "<input type='file' name='file' lay-type='file' _url='{$url}' onclick=\"c_up(this,'add')\">";
   } 
   return $html;
}